package _tema6;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.Vector;

public class ServidorThread extends Thread {
	private Socket s;
	private PanelControlServidor pnl;

	
	public ServidorThread(Socket s,PanelControlServidor pnl) {
		this.s = s;
		this.pnl = pnl;
	}

	public void run() {
		Requerimiento  requerimientoAux;
		Respuesta respuestaAux;
		
		try {
			ObjectOutputStream oos = new ObjectOutputStream(this.s.getOutputStream());
			ObjectInputStream ois = new ObjectInputStream(this.s.getInputStream());
			requerimientoAux = (Requerimiento)ois.readObject();
			while (Requerimiento.DESCONECTAR!=requerimientoAux.getTipo()){
				this.pnl.jtaAppendText(this.getName()+" (" + this.descripcionTipoRequerimiento(requerimientoAux.getTipo()) + ") " + requerimientoAux.getDato() + "\n");
				respuestaAux = this.procesarRequerimiento(requerimientoAux);	
				oos.writeObject(respuestaAux);
				requerimientoAux = (Requerimiento)ois.readObject();
			}
			this.pnl.jtaAppendText(this.getName()+" (" + this.descripcionTipoRequerimiento(requerimientoAux.getTipo()) + ") " + requerimientoAux.getDato() + "\n");
			oos.close();
			ois.close();
			this.s.close();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	private Respuesta procesarRequerimiento(Requerimiento requerimientoAux) throws Exception {
		Respuesta respuestaAux;
		String dsn = "jdbc:odbc:jugadores";
		Connection con;
		ResultSet rst;
		Vector<String> auxVecStr;
		
		Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
		con = DriverManager.getConnection(dsn,"sa","sa");

		auxVecStr = new Vector<String>();
		
		respuestaAux = new Respuesta();
		switch(requerimientoAux.getTipo()){
			case  Requerimiento.CONECTAR:
				/*Tenemos que mandarle un array con los SP*/
				respuestaAux.setTipo(1);
				/*Buscamos los SP disponibles*/
				Statement stm = con.createStatement();
				rst = stm.executeQuery("Select name from sysobjects where type= 'P'");
				while (rst.next()) 
				{
					auxVecStr.add(rst.getString("name"));
				}
				rst.close();
				stm.close();
				respuestaAux.setTitulos(auxVecStr.toArray());
				break;
				
			case Requerimiento.DESCONECTAR:
			
				break;
				
			case Requerimiento.REQUERIR:
				respuestaAux.setTipo(2);
				CallableStatement cstmt = con.prepareCall("{call "+requerimientoAux.getDato()+" (?,?)}");
				cstmt.setLong(1,requerimientoAux.getArgumentos()[1]);
				cstmt.setLong(2,requerimientoAux.getArgumentos()[0]);
				rst = cstmt.executeQuery();
				ResultSetMetaData rsmtd = rst.getMetaData();
				/*Headers*/
				String[] columnas = new String[rsmtd.getColumnCount()];
				for (int i = 1; i <= rsmtd.getColumnCount(); i++) {
					columnas[i-1] = rsmtd.getColumnName(i);
	            }
				respuestaAux.setTitulos(columnas);
				Object[] valscol;
				Vector<Object[]> vector = new Vector<Object[]>();
				while (rst.next()){
					valscol = new Object[rsmtd.getColumnCount()];
					for (int j = 1; j <= rsmtd.getColumnCount(); j++) {
						valscol[j-1] = rst.getObject(j);
					}
					vector.add(valscol);
				}
				Object[][] datos = new Object[vector.size()][rsmtd.getColumnCount()];
				vector.copyInto(datos);
				respuestaAux.setDatos(datos);
				rst.close();
				cstmt.close();
				break;
		}
		con.close();
		return respuestaAux;
	}

	private String descripcionTipoRequerimiento(int tipo){
		switch(tipo){
			case 1: return "CONECTAR";	
			case 2:	return "DESCONECTAR";
			case 3:	return "REQUERIR";
		}
		return "REQUERIMIENTO INVALIDO";
	}

}
